<template>
  <div class="users">
    <!-- 面包屑 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
      <el-breadcrumb-item>用户列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 搜索框 -->
    <el-input placeholder="请输入用户名" v-model="searchUser" class="search-input">
      <el-button @click="search" slot="append" icon="el-icon-search" type="primary" plain></el-button>
    </el-input>
    <el-button @click="handleAdd" type="primary" plain>添加用户</el-button>
    <!-- 表格 -->
    <el-table
      v-loading="loading"
      class="mt-15 mb-15"
      :data="tableData"
      border
      style="width: 100%">
      <el-table-column
        type="index"
        width="50">
      </el-table-column>
      <el-table-column
        prop="username"
        label="用户名">
      </el-table-column>
      <el-table-column
        prop="email"
        label="邮箱">
      </el-table-column>
      <el-table-column
        prop="mobile"
        label="电话">
      </el-table-column>
      <el-table-column
        label="状态">
        <!-- 往组件中添加标签或组件，需要使用作用域插槽 -->
        <!-- row是组件传回的行数据，里面包含该行所有数据 -->
        <!-- 限定admin用户不可修改状态 -->
        <template slot-scope="scope">
          <el-switch
            :disabled="scope.row.username==='admin'"
            v-model="scope.row.mg_state"
            active-color="#13ce66"
            inactive-color="#ff4949"
            @change="changeUserState(scope.row)">
          </el-switch>
        </template>
      </el-table-column>
      <!-- 操作 -->
      <el-table-column
        label="操作">
        <template slot-scope="scope">
          <el-button type="primary" icon="el-icon-edit" plain size="mini" @click="handleEdit(scope.row)"></el-button>
          <el-button type="danger" icon="el-icon-delete" plain size="mini" @click="handleDelete(scope.row)" :disabled="scope.row.username==='admin'"></el-button>
          <el-button type="success" icon="el-icon-check" circle size="mini" @click="handleRole(scope.row)" :disabled="scope.row.username==='admin'"></el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <el-pagination
      class="page"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage"
      :page-sizes="[5, 10, 15, 20]"
      :page-size="pagesize"
      :total="total"
      layout="total, sizes, prev, pager, next, jumper">
    </el-pagination>
    <!-- 添加用户弹框 -->
    <el-dialog title="添加用户" :visible.sync="addDialogFormVisible">
      <!-- addForm表单数据，:rules属性传入校验规则，prop指定需要校验的字段名 -->
      <el-form :model="addForm" :rules="addrules" ref="addRef">
        <el-form-item label="用户名" :label-width="formLabelWidth" prop="username">
          <el-input v-model="addForm.username" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="密码" :label-width="formLabelWidth" prop="password">
          <el-input v-model="addForm.password" type="password" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" :label-width="formLabelWidth" prop="email">
          <el-input v-model="addForm.email" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="电话" :label-width="formLabelWidth" prop="mobile">
          <el-input v-model="addForm.mobile" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addDialogFormVisible=false">取 消</el-button>
        <el-button type="primary" @click="confirmAdd">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 编辑用户弹框 -->
    <el-dialog title="编辑信息" :visible.sync="editDialogFormVisible">
      <!-- addForm表单数据，:rules属性传入校验规则，prop指定需要校验的字段名 -->
      <el-form :model="editForm" :rules="editrules" ref="editRef">
        <el-form-item label="用户名" :label-width="formLabelWidth" prop="username">
          <el-input v-model="editForm.username" autocomplete="off" disabled></el-input>
        </el-form-item>
        <el-form-item label="邮箱" :label-width="formLabelWidth" prop="email">
          <el-input v-model="editForm.email" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="电话" :label-width="formLabelWidth" prop="mobile">
          <el-input v-model="editForm.mobile" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editDialogFormVisible=false">取 消</el-button>
        <el-button type="primary" @click="confirmEdit">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 用户角色弹框 -->
    <el-dialog title="分配角色" :visible.sync="roleDialogFormVisible">
      <!-- addForm表单数据，:rules属性传入校验规则，prop指定需要校验的字段名 -->
      <el-form :model="roleForm" :rules="editrules">
        <el-form-item label="当前用户" :label-width="formLabelWidth" prop="username">
          <el-input v-model="roleForm.username" autocomplete="off" disabled></el-input>
        </el-form-item>
        <el-form-item label="用户角色" :label-width="formLabelWidth" prop="id">
          <el-select v-model="selectRoleId" placeholder="请选择">
            <el-option
              v-for="item in option"
              :key="item.value"
              :label="item.roleName"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="roleDialogFormVisible=false">取 消</el-button>
        <el-button type="primary" @click="confirmRole">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getUsers, changeState, addUser, editUser, deleteUser, getRoles, confirmUserRole } from '@/api'
export default {
  data () {
    // 校验邮箱函数，在return外面定义
    let checkEmail = (rule, value, cb) => {
      if (value === '') {
        cb(new Error('请输入邮箱地址'))
      } else {
        // 正则校验邮箱格式
        let emailReg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}/
        if (emailReg.test(value)) {
          cb() // 校验通过
        } else {
          cb(new Error('请输入正确的邮箱格式'))
        }
      }
    }
    // 校验手机号码
    let checkMobile = (rule, value, cb) => {
      if (value === '') {
        cb(new Error('请输入手机号码'))
      } else {
        let mobileReg = /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/
        if (mobileReg.test(value)) {
          cb()
        } else {
          cb(new Error('请输入正确的手机格式'))
        }
      }
    }
    // 编辑用户信息校验
    let checkEditEmail = (rule, value, cb) => {
      if (value === '') {
        cb()
      } else {
        // 正则校验邮箱格式
        let emailReg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}/
        if (emailReg.test(value)) {
          cb() // 校验通过
        } else {
          cb(new Error('请输入正确的邮箱格式'))
        }
      }
    }
    let checkEditMobile = (rule, value, cb) => {
      if (value === '') {
        cb()
      } else {
        let mobileReg = /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/
        if (mobileReg.test(value)) {
          cb()
        } else {
          cb(new Error('请输入正确的手机格式'))
        }
      }
    }
    return {
      loading: false, // 加载动画
      currentPage: 1, // 当前页码
      total: 0, // 数据总条数
      pagesize: 10, // 每页默认10条
      pagenum: 1, // 默认第一页
      searchUser: '', // 搜索用户
      tableData: [], // 表格数据
      addDialogFormVisible: false, // 显示弹框
      // 添加用户表单数据
      addForm: {
        username: '',
        password: '',
        email: '',
        mobile: ''
      },
      formLabelWidth: '20%', // 字段宽度
      // 校验规则
      addrules: {
        username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
        password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
        // 自定义校验规则，validator 属性值是一个函数
        email: [{ required: true, validator: checkEmail, trigger: 'blur' }],
        // 自定义校验规则
        mobile: [{ required: true, validator: checkMobile, trigger: 'blur' }]
      },
      // 编辑用户信息弹框
      editDialogFormVisible: false, // 控制编辑信息弹框
      // 编辑用户信息表单
      editForm: {
        username: '',
        email: '',
        mobile: '',
        id: ''
      },
      // 编辑用户的校验
      editrules: {
        // 自定义校验规则，validator 属性值是一个函数
        email: [{ validator: checkEditEmail, trigger: 'blur' }],
        // 自定义校验规则
        mobile: [{ validator: checkEditMobile, trigger: 'blur' }]
      },
      // 分配用户角色
      roleDialogFormVisible: false, // 控制角色弹框显示
      // 用户角色
      roleForm: {
        username: '',
        id: ''
      },
      // 用户角色列表
      selectRoleId: '',
      // 选择器数据
      option: []
    }
  },
  created () {
    // 初始化表格数据
    this.initTable()
  },
  methods: {
    // 初始化表格数据
    initTable () {
      // 显示加载中
      this.loading = true
      let obj = { query: this.searchUser, pagenum: this.pagenum, pagesize: this.pagesize }
      getUsers(obj).then(res => {
        // console.log(res)
        if (res.data.meta.status === 200) {
          this.tableData = res.data.data.users
          this.total = res.data.data.total
          this.pagenum = res.data.data.pagenum
          this.$message.success(res.data.meta.msg)
        } else {
          this.$message.error(res.data.meta.msg)
        }
        // 加载完毕
        this.loading = false
      }).catch(err => {
        console.log(err)
      })
    },
    // 搜索用户
    search () {
      this.initTable()
    },
    // 修改用户状态
    changeUserState (row) {
      // console.log(row)
      changeState(row.id, row.mg_state)
        .then(res => {
          // console.log(res)
          if (res.data.meta.status === 200) {
            this.$message.success(res.data.meta.msg)
          } else {
            this.$message.error(res.data.meta.msg)
          }
          this.initTable()
        }).catch(err => {
          console.log(err)
        })
    },
    // 添加用户
    handleAdd () {
      this.addDialogFormVisible = true
      // 上面的赋值操作是一个异步操作，如果直接获取ref 的dom引用可能会报错，
      // 解决方法是将dom操作放在this.$nextTick方法中
      this.$nextTick(() => {
        this.$refs.addRef.clearValidate()
      })
    },
    // 确认添加用户
    confirmAdd () {
      // 提交添加用户时需要进行js校验
      this.$refs.addRef.validate(isPass => {
        if (isPass) {
          addUser(this.addForm)
            .then(res => {
              console.log(res)
              if (res.data.meta.status === 201) {
                // 成功弹框
                this.$message.success(res.data.meta.msg)
                // 清空表单数据
                this.addForm.username = ''
                this.addForm.password = ''
                this.addForm.email = ''
                this.addForm.mobile = ''
                // 隐藏弹框
                this.addDialogFormVisible = false
                // 初始化表格
                this.initTable()
              } else {
                this.$message.error(res.data.meta.msg)
              }
            }).catch(err => {
              console.log(err)
            })
        } else {
          // 表单js校验不通过
          this.$message.error('表单格式不正确，请重新输入')
        }
      })
    },
    // 编辑用户信息
    handleEdit (row) {
      // console.log(row)
      // 显示
      this.editDialogFormVisible = true
      // 赋值到界面
      this.editForm.username = row.username
      this.editForm.email = row.email
      this.editForm.mobile = row.mobile
      this.editForm.id = row.id
      // 清除验证结果
      this.$nextTick(() => {
        this.$refs.editRef.clearValidate()
      })
    },
    // 确认编辑信息
    confirmEdit () {
      // console.log(this.editForm)
      this.$refs.editRef.validate(isPass => {
        if (isPass) {
          editUser(this.editForm)
            .then(res => {
              // console.log(res)
              if (res.data.meta.status === 200) {
                // 更新成功弹框
                this.$message.success(res.data.meta.msg)
                // 清空表单数据
                this.editForm.username = ''
                this.editForm.id = ''
                this.editForm.email = ''
                this.editForm.mobile = ''
                // 隐藏弹框
                this.editDialogFormVisible = false
                // 初始化表格
                this.initTable()
              } else {
                this.$message.error(res.data.meta.msg)
              }
            }).catch(err => {
              console.log(err)
            })
        } else {
          // 表单js校验不通过
          this.$message.error('表单格式不正确，请重新输入')
        }
      })
    },
    // 删除用户
    handleDelete (row) {
      // 弹框确认
      this.$confirm('此操作将永久删除该用户, 是否继续?', '注意', {
        confirmButtonText: '删除',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 确认的回调
        // 删除用户请求
        deleteUser(row.id).then(res => {
          // console.log(res)
          if (res.data.meta.status === 200) {
            this.$message.success(res.data.meta.msg)
            this.initTable()
          } else {
            this.$message.error(res.data.meta.msg)
          }
        }).catch(err => {
          console.log(err)
        })
      }).catch(() => {
        // 取消的回调
        this.$message.info({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    // 分配用户角色
    handleRole (row) {
      // console.log(row)
      this.roleDialogFormVisible = true
      // 当前用户角色数据
      this.roleForm.username = row.username
      this.roleForm.id = row.id
      this.selectRoleId = row.role_name
      getRoles().then(res => {
        this.option = res.data.data
      })
    },
    // 确认用户角色
    confirmRole () {
      if (typeof this.selectRoleId === 'string') {
        this.roleDialogFormVisible = false
        return
      }
      confirmUserRole(this.roleForm.id, this.selectRoleId).then(res => {
        // console.log(res)
        if (res.data.meta.status === 200) {
          this.$message.success(res.data.meta.msg)
          this.roleDialogFormVisible = false
          this.initTable()
        } else {
          this.$message.error(res.data.meta.msg)
        }
      }).catch(err => {
        console.log(err)
      })
    },
    // 每页条数
    handleSizeChange (val) {
      this.pagesize = val
      this.initTable()
    },
    // 跳转页码
    handleCurrentChange (val) {
      this.pagenum = val
      this.currentPage = val
      this.initTable()
    }
  }
}
</script>

<style lang="scss" scoped>
.search-input {
  width: 50%;
  margin-right: 20px;
}
.el-pagination {
  text-align: center;
}
</style>
